﻿using LxBasic;
using System.Collections.Generic;

namespace LxCore
{
    public abstract class TurbulenceSolver
    {
        public class Set : IterateSolver.Set<Unit>
        {
            public void UpdateGammaForMomentum()
            {
                if (IsEmpty) return;
                MultiThreads.RunParallelTask((i) =>
                {
                    foreach (var l in Solvers)
                    {
                        l.UpdateGammaForMomentum(i);
                    }
                });
            }
            public void UpdateGammaForTemperature()
            {
                if (IsEmpty) return;
                MultiThreads.RunParallelTask((i) =>
                {
                    foreach (var l in Solvers)
                    {
                        l.UpdateGammaForTemperature(i);
                    }
                });
            }
        }
        public class Unit : IterateSolver.Unit
        {
            public TurbulencekOmega[] Equations;
            public EquationConnectBase[] Connects;
            public Set InSolveSet;
            public NSEquation[] ks;
            public NSEquation[] ws;

            public void CheckCreate(object set, TurbulencekOmega[] equations, EquationConnectBase[] connects)
            {
                throw new NotImplementedException();
                CheckCreator.ArrayStrict(ref ks, Equations.Length);
                CheckCreator.ArrayStrict(ref ws, Equations.Length);
                for (int i1 = 0; i1 < Equations.Length; i1++)
                {
                    ks[i1] = Equations[i1].k;
                    ws[i1] = Equations[i1].w;
                }
            }
            public void UpdateGammaForMomentum(ThreadInfo threadInfo)
            {
                foreach (var com in Equations) { com.Cal_MomGamma(threadInfo); }
            }
            public void UpdateGammaForTemperature(ThreadInfo threadInfo)
            {
                foreach (var com in Equations) { com.Cal_TemperatureGamma(threadInfo); }
            }
            public override void Solve_Steady()
            {
                //k
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in Equations) { com.Cal_kGamma(threadInfo); }
                });
                prepareMatrix(ks);
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in Equations) { com.Add_k_Ab_byConstitutiveEquation(threadInfo); }
                });
                RelaxSolveLimit(ks, Connects);
                updateBoundAndLimit(ks);
                //w
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in Equations) { com.Cal_wGamma(threadInfo); }
                });
                prepareMatrix(ws);
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in Equations) { com.Set_w_Ab_byConstitutiveEquation_AfterSetAll(threadInfo); }
                });
                RelaxSolveLimit(ws, Connects);
                updateBoundAndLimit(ws);
            }
            protected void prepareMatrix(IEnumerable<NSEquation> kews)
            {
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in kews) { com.CalGradient_LSQ(threadInfo); }
                });
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in kews) { com.FormABOnFaces(threadInfo); }
                });
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in kews) { com.FormABOnCells(threadInfo); }
                });
            }
            protected void updateBoundAndLimit(IEnumerable<NSEquation> kews)
            {
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in kews) { com.UpdateBoundsValue(threadInfo); }
                });
                foreach (var com in kews) { com.LimitScalarValue(); }
            }
            public override void Solve_ImplicitTrans()
            {
                //k
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in Equations) { com.Cal_kGamma(threadInfo); }
                });
                prepareMatrix(ks);
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in ks) { com.TransData.FormAb_ImplicitTrans(threadInfo); }
                });
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in Equations) { com.Add_k_Ab_byConstitutiveEquation(threadInfo); }
                });
                RelaxSolveLimit(ks, Connects);
                updateBoundAndLimit(ks);
                //w
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in Equations) { com.Cal_wGamma(threadInfo); }
                });
                prepareMatrix(ws);
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in ws) { com.TransData.FormAb_ImplicitTrans(threadInfo); }
                });
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in Equations) { com.Set_w_Ab_byConstitutiveEquation_AfterSetAll(threadInfo); }
                });
                RelaxSolveLimit(ws, Connects);
                updateBoundAndLimit(ws);
            }
            public override void Solve_ExplicitTrans()
            {
                //k
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in Equations) { com.Cal_kGamma(threadInfo); }
                });
                prepareMatrix(ks);
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in ks) { com.TransData.FormAb_ExplicitTrans(threadInfo); }
                });
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in Equations) { com.Add_k_Ab_byConstitutiveEquation(threadInfo); }
                });
                SolveExplicit(ks, Connects);
                updateBoundAndLimit(ks);
                //w
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in Equations) { com.Cal_wGamma(threadInfo); }
                });
                prepareMatrix(ws);
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in ws) { com.TransData.FormAb_ExplicitTrans(threadInfo); }
                });
                MultiThreads.RunParallelTask((threadInfo) =>
                {
                    foreach (var com in Equations) { com.Set_w_Ab_byConstitutiveEquation_AfterSetAll(threadInfo); }
                });
                SolveExplicit(ws, Connects);
                updateBoundAndLimit(ws);
            }

            public override void SaveOldValue()
            {
                throw new NotImplementedException();
            }
        }
    }

}
//public List<TurbulencekOmega> kwZoneStore = new();
//public List<ConnectWallBase> kwJointStore = new List<ConnectWallBase>();//暂时不用，占位

//public override void Rearrange(ConnectivitySolver connectivityAnalysis)
//{
//    var r = connectivityAnalysis.GetConnectivity(kwZoneStore, kwJointStore);
//    Solvers = new List<RANSkwUnit>(r.Count);
//    foreach (var l in r)
//    {
//        RANSkwUnit u = new RANSkwUnit();
//        u.CreateUnit(l.Zones, l.Joints);
//        Solvers.Add(u);
//    }
//    kwZoneStore.Clear();
//    kwJointStore.Clear();
//}
//public void UpdateGammaForMomentum(ThreadInfo threadInfo)
//{
//    foreach (var u in Units)
//    {
//        u.UpdateGammaForMomentum(threadInfo);
//    }
//}

//public void UpdateGammaForTemperature(ThreadInfo threadInfo)
//{
//    foreach (var u in Units)
//    {
//        u.UpdateGammaForTemperature(threadInfo);
//    }
//}
//public void Addkew(TurbulenceModelkw kew)
//{
//    kws.Add(kew);
//    ks.Add(kew.k);
//    ws.Add(kew.w);
//}
//public RANSkwUnit kwStor { get; set; }
//public override void Clear()
//{
//    base.Clear();
//    kwStor = new RANSkwUnit();
//}